package com.stu.chart.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.stu.chart.entity.ChartContent;
import com.stu.chart.entity.PublichEvaluate;
import com.stu.chart.entity.Staff;
import com.stu.chart.entity.UserPublish;
import com.stu.chart.mapper.UserPublishMapper;
import com.stu.chart.service.ChartContentService;
import com.stu.chart.service.PublichEvaluateService;
import com.stu.chart.service.StaffService;
import com.stu.chart.service.UserPublishService;
import com.stu.chart.util.CalXieUtil;
import com.stu.chart.util.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 *@author dsj
 */
@Service
public class UserPublishServiceImpl extends ServiceImpl<UserPublishMapper, UserPublish>
    implements UserPublishService{
    @Autowired
    private PublichEvaluateService publichEvaluateService;
    @Autowired
    private ChartContentService chartContentService;
    @Autowired
    @Lazy
    private StaffService staffService;

    @Override
    public List<Staff> recommand(String username) {
        username = SecurityUtil.getUser().getUsername();
        List<PublichEvaluate> publichEvaluates = publichEvaluateService.listAll();
        List<ChartContent> listSend = chartContentService.list(Wrappers.lambdaQuery(ChartContent.class).eq(ChartContent::getSend,username));
        List<ChartContent> listRecive = chartContentService.list(Wrappers.lambdaQuery(ChartContent.class).eq(ChartContent::getRecive,username));
        Map<String,Integer> personToPerson = new HashMap<>();
        for (int i = 0; i < listSend.size(); i++) {
            ChartContent chartContent = listSend.get(i);
            String key = chartContent.getSend()+"@_@"+chartContent.getRecive();
            if(personToPerson.containsKey(key)){
                personToPerson.put(key,personToPerson.get(key)+1);
            }else{
                personToPerson.put(key,1);
            }
        }
        for (int i = 0; i < listRecive.size(); i++) {
            ChartContent chartContent = listRecive.get(i);
            String key = chartContent.getRecive()+"@_@"+chartContent.getSend();
            if(personToPerson.containsKey(key)){
                personToPerson.put(key,personToPerson.get(key)+1);
            }else{
                personToPerson.put(key,1);
            }
        }
        // 通过用户对发文打分以及 用户与用户之间聊天次数 进行 相似度推荐和权重推荐
        Map<String, Map<String, Integer>> userPerfMap = new HashMap<>();
        for (int i = 0; i <publichEvaluates.size() ; i++) {
            PublichEvaluate publichEvaluate = publichEvaluates.get(i);
            String  userId = publichEvaluate.getUsername()+"";
            String publishId = publichEvaluate.getPublishId()+"";
            Integer count = publichEvaluate.getEvaluateNum();
            HashMap<String,Integer> data = new HashMap<>();
            data.put(publishId,powerCal(count,personToPerson,userId,username));
            userPerfMap.put(userId,data);
        }
        Map<String, Double> simUserSim = CalXieUtil.getSimUserSim(userPerfMap, username, 2);
        Set<String> strings = simUserSim.keySet();
        List<Staff> re = new ArrayList<>();
        if(strings.size()>0){
            List<Staff> listRecommand = staffService.list(Wrappers.lambdaQuery(Staff.class).in(Staff::getUsername, strings));
            listRecommand.forEach(e->{
                e.setIsRecommand(1);
            });
            List<Staff> listNotRecommand = staffService.list(Wrappers.lambdaQuery(Staff.class).notIn(Staff::getUsername, strings));
            re.addAll(listRecommand);
            if(listNotRecommand.size()>0){
                re.addAll(listNotRecommand);
            }
        }else{
            List<Staff> listNotRecommand = staffService.list();
            re.addAll(listNotRecommand);
        }

        return re;
    }

    private Integer powerCal(Integer count, Map<String, Integer> personToPerson,String otherUser,String myself) {
        if(personToPerson != null && personToPerson.size()>0){
            int sum = personToPerson.values().stream().mapToInt(e -> e).sum();
            String key = myself +"@_@"+otherUser;
            Integer integer = personToPerson.get(key);
            int per = integer != null?(integer*(2)/sum):0;
            return count+per;
        }
        return count;
    }
}




